#ifndef AVALON_PIPEDREADER_HPP
#define AVALON_PIPEDREADER_HPP
#include "Avalon/IO/Buffer.hpp"
#include "Avalon/IO/Reader.hpp"
#include "Avalon/Threading/Async.hpp"

namespace Avalon {
namespace IO {

  /*! \class PipedReader
   *  \brief Reads the contents written by a PipedWriter.
   *  \author Kamal Mansouri <kranar@hotmail.com>
   */
  class PipedReader : public Reader {
    public:

      //! Constructs a PipedReader.
      PipedReader();

      virtual ~PipedReader();

      //! Breaks the pipe.
      void Break();

      virtual bool IsAtEndOfDataSource();

      virtual Threading::Async<int>::Ptr Read(void* destination, int size);

      virtual Threading::Async<int>::Ptr Read(Buffer* destination, int size);

      using Reader::Read;

    private:
      friend class PipedWriter;
      boost::shared_ptr<boost::recursive_mutex> m_mutex;
      Buffer m_data;
      int m_sizeRemaining;
      Threading::AsyncOwner<int>::Ptr m_nextReadResult;
      int m_nextReadSize;
      void* m_destination;
      Buffer* m_destinationBuffer;
      PipedWriter* m_writer;

      void Connect(PipedWriter* writer);
      void InternalBreak();
      void Write(const void* data, int size);
      int CopyOver();
  };
}
}

#endif // AVALON_PIPEDREADER_HPP
